//################################################################################
// MIT License
// Copyright (c) 2024 ZhangYihua
//
// Change Logs:
// Date           Author       Notes
// 2023-11-03     ZhangYihua   first version
//
// Description  : 
//################################################################################

module s_sat#(
parameter           IW                      = 9,    // IW>=OW
parameter           OW                      = 8
) ( 
input       signed  [IW-1:0]                id,
output      signed  [OW-1:0]                od
);

//################################################################################
// define local varialbe and localparam
//################################################################################
localparam          HW                      = IW-OW+1;

wire                [HW-1:0]                hd;
wire                                        all_one;
wire                                        all_zero;
wire                                        over;
wire                                        is;
wire        signed  [OW-1:0]                opeak;

//################################################################################
// main
//################################################################################

assign hd = id[IW-1:OW-1];

assign all_one  = &hd;
assign all_zero = ~(|hd);

assign over = (~all_one) & (~all_zero);

assign is = id[IW-1]; 
assign opeak = {OW{is}} ^ ({OW{1'b1}}>>1); // reverse lower bits, keep sign bit, OW==1 is legal

assign od = (over==1'b0) ? id[OW-1:0] : opeak;

//################################################################################
// ASSERTION
//################################################################################

`ifdef CBB_ASSERT_ON
// synopsys translate_off


// synopsys translate_on
`endif

endmodule
